package com.znjc.device.service.impl;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.znjc.common.constant.DeviceConstants;
import com.znjc.common.core.domain.entity.SysDept;
import com.znjc.common.core.domain.entity.SysDictData;
import com.znjc.common.utils.StringUtils;
import com.znjc.device.domain.*;
import com.znjc.device.domain.vo.DeviceSystemStatus;
import com.znjc.device.domain.vo.DeviceTypeVO;
import com.znjc.device.domain.vo.DeviceVO;
import com.znjc.device.domain.vo.HomePageDataVO;
import com.znjc.device.mapper.IotSerialMapper;
import com.znjc.device.service.*;
import com.znjc.device.util.DataUtil;
import com.znjc.device.util.DateUtil;
import com.znjc.device.websocket.WebSocketUsers;
import com.znjc.system.service.ISysDeptService;
import com.znjc.system.service.ISysDictDataService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.sql.Timestamp;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

import static com.znjc.common.utils.Threads.sleep;

/**
 * 【串口管理】Service业务层处理
 *
 * @author zengpc
 * @date 2023-12-04
 */
@Service
public class IotSerialServiceImpl extends ServiceImpl<IotSerialMapper, IotSerial> implements IIotSerialService {
    @Resource
    private IIotDataCheckService iotDataCheckService;
    @Resource
    private IIotDataResRuleService iotDataResRuleService;
    @Resource
    private IDeviceRuleRefService deviceRuleRefService;
    @Resource
    IDevicePointService devicePointService;
    @Resource
    IDeviceDeviceService deviceDeviceService;
    @Resource
    ISysDictDataService sysDictDataService;
    @Resource
    DeviceDataService deviceDataService;
    @Resource
    private IDeviceTypeSerialRefService deviceTypeSerialRefService;
    @Resource
    private IDeviceAlarmService deviceAlarmService;
    @Autowired
    private ISysDeptService deptService;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;
    @Autowired
    private IDeviceCommandService deviceCommandService;
    @Autowired
    private IIotSerialService iotSerialService;

    @PostConstruct
    public void init() {
        LambdaUpdateWrapper<IotSerial> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(IotSerial::getDeviceType,"3");
        updateWrapper.set(IotSerial::getGatherType,"1");
        this.update(updateWrapper);
    }

    @Override
    public void analyzeData(JSONObject data) throws Exception {
        String clientId = data.getString("clientId");
        String needData = data.getString("needData");
        String date = data.getString("date");
        List<String> dataList = DataUtil.packData(needData);
        SysDictData dictData = new SysDictData();
        dictData.setDictType(DeviceConstants.DEVICE_TLV);
        List<SysDictData> tlvs = sysDictDataService.selectDictDataList(dictData);
        if (CollectionUtils.isEmpty(tlvs)) {
            return;
        }
        for (SysDictData tlv : tlvs) {
            String code = tlv.getDictValue();
            if ("0A".equals(code)) {
                dataList = analyzeSysStatus(dataList, clientId);
            } else if ("0B".equals(code)) {
                analyzeDevice(dataList, clientId, date);
            } else {
                dataList = analyzeTlv(code, dataList, clientId, date);
            }
        }


    }

    /**
     * 解析测量数据
     *
     * @param dataList
     * @param clientId
     * @param date
     */
    private void analyzeDevice(List<String> dataList, String clientId, String date) {
        /***解析设备数据***/
        //根据部门id查询部门下的设备
        List<DeviceDevice> devices = deviceDeviceService.getListByDeptId(Long.parseLong(clientId));
        if (CollectionUtils.isEmpty(devices)) {
            return;
        }
        //确认真实数据
        if (dataList.contains("0B")) {
            List<String> datas = dataList.subList(0, dataList.size() - 2);
            String realDatas = DataUtil.packRealDatas(datas);
            if (StringUtils.isEmpty(realDatas)) {
                return;
            }
            //根据设备c1p1+c2p2+对象编码锁定数据，再根据设备绑定的测点和测点对应的解析方式获取最终数据
            analyzeDeviceData(devices, realDatas, date);
        }
    }

    /**
     * 解析tlv数据
     *
     * @param dataList
     * @param clientId
     */
    private List<String> analyzeTlv(String code, List<String> dataList, String clientId, String date) throws Exception {
        List<String> datas = new ArrayList<>();
        if (dataList.indexOf(code) == 0) {
            Integer dataLen = Integer.parseInt(dataList.get(1), 16);
            dataList.remove(0);
            dataList.remove(0);
            datas = dataList.subList(0, dataLen);
            dataList = dataList.subList(dataLen, dataList.size());
        }
        //List<DeviceData> deviceDatas = new ArrayList<>();
        //磁芯电流采集板 4位通道一组
        if ("01".equals(code)) {
            if (CollectionUtils.isNotEmpty(datas)) {
                packcx(4, datas, date);
            }
        }
        //回流电流采集板 6位通道一组
        else if ("02".equals(code)) {
            if (CollectionUtils.isNotEmpty(datas)) {
                packhl(6, datas, date);
            }
        }
        //通道转换版 6位通道一组
        else if ("03".equals(code)) {
            if (CollectionUtils.isNotEmpty(datas)) {
                packzhb(datas, date,clientId);
            }
        }
        //逆变器
        else if ("06".equals(code)) {
            if (CollectionUtils.isNotEmpty(datas)) {
                packnbq(datas, date);
            }
        }
        /*if (CollectionUtils.isNotEmpty(deviceDatas)) {
            deviceDataService.saveBatch(deviceDatas);
        }*/
        return dataList;
    }

    /**
     * 封装磁芯电流
     * @param len
     * @param datas
     * @param date
     */
    private  void packcx(int len, List<String> datas, String date) throws Exception {
        CxData entity = new CxData();
        entity.setTs(DateUtil.StringToTimestamp(date));
        while (datas.size() > 0) {
            //地址位
            String data = datas.subList(0, 1).stream().collect(Collectors.joining());
            entity.setDzw(data);
            //deviceDatas.add(packTlvData(data, deviceName, "地址位", date, "",dataType));
            datas = datas.subList(1, datas.size());
            int maxNum = 0;
            for (int i = 0; i < len; i++) {
                data = datas.subList(0, datas.size() == 4 ? datas.size() : 4).stream().collect(Collectors.joining());
                data = String.valueOf(Integer.parseInt(data, 16));
                data = new BigDecimal(data).divide(new BigDecimal("1000")).setScale(2,BigDecimal.ROUND_HALF_UP).toPlainString();
                if(i == 0){
                    entity.setDl1(data);
                }else if(i == 1){
                    entity.setDl2(data);
                }else if(i == 2){
                    entity.setDl3(data);
                }else if(i == 3){
                    entity.setDl4(data);
                }else if(i == 4){
                    entity.setDl5(data);
                }else if(i == 5){
                    entity.setDl6(data);
                }else if(i == 6){
                    entity.setDl7(data);
                }else if(i == 7){
                    entity.setDl8(data);
                }else if(i == 8){
                    entity.setDl9(data);
                }else if(i == 9){
                    entity.setDl10(data);
                }
                //deviceDatas.add(packTlvData(data, deviceName, "第" + (i + 1) + "通道电流", date, "mA",dataType));
                datas = datas.subList(datas.size() == 4 ? datas.size() : 4, datas.size());
                maxNum=i+1;
            }
            entity.setMaxDlw(maxNum);
            SysDictData sysDictData = new SysDictData();
            sysDictData.setDictType(DeviceConstants.DEVICE_CX_NAMES);
            entity.setDictData(sysDictDataService.selectDictDataList(sysDictData).stream().map(SysDictData::getDictLabel).collect(Collectors.toList()));
        }
        deviceDataService.saveCx(entity);
    }

    /**
     * 封装回流电流
     * @param len
     * @param datas
     * @param date
     */
    private  void packhl(int len, List<String> datas, String date) throws Exception {
        HlData entity = new HlData();
        entity.setTs(DateUtil.StringToTimestamp(date));

        while (datas.size() > 0) {
            //地址位
            String data = datas.subList(0, 1).stream().collect(Collectors.joining());
            entity.setDzw(data);
            //deviceDatas.add(packTlvData(data, deviceName, "地址位", date, "",dataType));
            datas = datas.subList(1, datas.size());
            int maxNum = 0;
            for (int i = 0; i < len; i++) {
                data = datas.subList(0, datas.size() == 4 ? datas.size() : 4).stream().collect(Collectors.joining());
                data = String.valueOf(Integer.parseInt(data, 16));
                data = new BigDecimal(data).divide(new BigDecimal("1000")).setScale(2,BigDecimal.ROUND_HALF_UP).toPlainString();
                if(i == 0){
                    entity.setDl1(data);
                }else if(i == 1){
                    entity.setDl2(data);
                }else if(i == 2){
                    entity.setDl3(data);
                }else if(i == 3){
                    entity.setDl4(data);
                }else if(i == 4){
                    entity.setDl5(data);
                }else if(i == 5){
                    entity.setDl6(data);
                }else if(i == 6){
                    entity.setDl7(data);
                }else if(i == 7){
                    entity.setDl8(data);
                }else if(i == 8){
                    entity.setDl9(data);
                }else if(i == 9){
                    entity.setDl10(data);
                }else if(i == 10){
                    entity.setDl11(data);
                }else if(i == 11){
                    entity.setDl12(data);
                }else if(i == 12){
                    entity.setDl13(data);
                }else if(i == 13){
                    entity.setDl14(data);
                }else if(i == 14){
                    entity.setDl15(data);
                }else if(i == 15){
                    entity.setDl16(data);
                }
                maxNum=i+1;
                //deviceDatas.add(packTlvData(data, deviceName, "第" + (i + 1) + "通道电流", date, "mA",dataType));
                datas = datas.subList(datas.size() == 4 ? datas.size() : 4, datas.size());
            }
            entity.setMaxDlw(maxNum);
            SysDictData sysDictData = new SysDictData();
            sysDictData.setDictType(DeviceConstants.DEVICE_HL_NAMES);
            entity.setDictData(sysDictDataService.selectDictDataList(sysDictData).stream().map(SysDictData::getDictLabel).collect(Collectors.toList()));
        }

        deviceDataService.saveHl(entity);
    }

    /**
     * 通道转换版
     *
     * @param datas
     * @param date
     * @return
     */
    private void packzhb(List<String> datas, String date,String deptId) throws Exception {
        //List<DeviceData> deviceDatas = new ArrayList<>();

        //Integer dataType = 3;
        DeviceBoard board;
        TdzhbData entity = new TdzhbData();
        entity.setTs(DateUtil.StringToTimestamp(date));
        while (datas.size() > 0) {
            //地址位
            String data = datas.subList(0, 1).stream().collect(Collectors.joining());
            String tdh = data;
            //deviceDatas.add(packTlvData(data, "通道转换板", "地址位", date, "",dataType));

            datas = datas.subList(1, datas.size());
            for (int i = 0; i < 1; i++) {
                data = datas.subList(0, datas.size() == 8 ? datas.size() : 8).stream().collect(Collectors.joining());
                if("01".equals(tdh)){
                    entity.setDz1(data);
                }else if("02".equals(tdh)){
                    entity.setDz2(data);
                }else if("03".equals(tdh)){
                    entity.setDz3(data);
                }else if("04".equals(tdh)){
                    entity.setDz4(data);
                }else if("05".equals(tdh)){
                    entity.setDz5(data);
                }else if("06".equals(tdh)){
                    entity.setDz6(data);
                }else if("07".equals(tdh)){
                    entity.setDz7(data);
                }else if("08".equals(tdh)){
                    entity.setDz8(data);
                }else if("09".equals(tdh)){
                    entity.setDz9(data);
                }else if("10".equals(tdh)){
                    entity.setDz10(data);
                }
                //deviceDatas.add(packTlvData(data, "通道转换板", tdh+"通道", date, "",dataType));
                datas = datas.subList(datas.size() == 8 ? datas.size() : 8, datas.size());
            }
        }
        deviceDataService.saveTdzhb(entity);
    }



    /**
     * 逆变器
     *
     * @param datas
     * @param date
     * @return
     */
    private void packnbq(List<String> datas, String date) throws Exception {
        NbqData entity = new NbqData();
        //直流电压
        String data = datas.subList(0, 4).stream().collect(Collectors.joining());
        data = String.valueOf(Integer.parseInt(data, 16));
        entity.setZldy(data);
        //deviceDatas.add(packTlvData(data, "逆变器", "直流电压", date, "mV",dataType));
        //交流电压
        data = datas.subList(4, 8).stream().collect(Collectors.joining());
        data = String.valueOf(Integer.parseInt(data, 16));
        entity.setJldy(data);
        //交流电流
        data = datas.subList(8, 12).stream().collect(Collectors.joining());
        data = String.valueOf(Integer.parseInt(data, 16));
        entity.setJldl(data);
        //频率
        data = datas.subList(12, 14).stream().collect(Collectors.joining());
        data = String.valueOf(Integer.parseInt(data, 16));
        entity.setPl(data);
        //温度1
        data = datas.subList(14, 16).stream().collect(Collectors.joining());
        data = String.valueOf(Integer.parseInt(data, 16));
        entity.setWd1(data);
        //温度2
        data = datas.subList(16, 18).stream().collect(Collectors.joining());
        data = String.valueOf(Integer.parseInt(data, 16));
        entity.setWd2(data);
        entity.setTs(DateUtil.StringToTimestamp(date));
        deviceDataService.saveNbq(entity);
    }

    /**
     * 解析系统状态
     *
     * @param dataList
     * @param clientId
     */
    private List<String> analyzeSysStatus(List<String> dataList, String clientId) {
        /***解析系统状态数据***/
        if (dataList.size() > 8) {
            List<String> sysStatus = dataList.subList(6, 8);
             String status = sysStatus.stream().collect(Collectors.joining());
            if (StringUtils.isNotEmpty(status)) {
                //16进制转2进制
                int decimal = Integer.parseInt(status, 16); // 先将十六进制转换为十进制
                String binary = Integer.toBinaryString(decimal); // 再将十进制转换为二进制
                packDeviceSystemStatus(binary, Long.parseLong(clientId));
            }
        }
        return dataList.subList(8, dataList.size());
    }

    /**
     * 解析单个设备下的数据
     *
     * @param devices
     * @param realDatas eg:12,13,01,00,00,00,7B,00,00,07,D0,00,00,0C,30,0D,AC,00,00,00,00
     */
    private void analyzeDeviceData(List<DeviceDevice> devices, String realDatas, String date) {
        List<DeviceData> addList = new ArrayList<>();
        List<DeviceAlarm> alarmList = new ArrayList<>();
        AtomicBoolean status = new AtomicBoolean(true);
        Map<Long, Boolean> statusMap = new HashMap<>();
        Map<String, String> redisDataList = new HashMap<>();
        devices.stream().forEach(device -> {
            List<String> codes = packDeviceAnalyzeStr(device);
            if(CollectionUtils.isNotEmpty(codes)){
                for(String code : codes){
                    if (StringUtils.isNotEmpty(code)) {
                        //根据设备c1p1+c2p2+对象编码锁定数据
                        if (realDatas.indexOf(code) >= 0) {
                            String data = realDatas.substring(realDatas.indexOf(code) + code.length());
                            List<DeviceRuleRef> ruleRefs = deviceRuleRefService.getListByDeviceId(device.getId());
                            if (CollectionUtils.isNotEmpty(ruleRefs)) {
                                AtomicInteger sliptNum = new AtomicInteger();
                                ruleRefs.forEach(pointRuleRef -> {
                                    IotDataResRule resRule = iotDataResRuleService.getById(pointRuleRef.getResRuleId());
                                    if (null != resRule && null != resRule.getDataNum()) {
                                        DeviceData deviceData = null;
                                        try {
                                            deviceData = packData(resRule, new ArrayList<>(Arrays.asList(data.split(","))), sliptNum.get(), resRule.getDataNum() + sliptNum.get(), device.getId(), pointRuleRef.getPointId(), date);
                                            //地址位
                                            String[] codeArr = code.split(",");
                                            deviceData.setAddress(codeArr[0]+"_"+codeArr[1]);
                                            deviceData.setDevice(device);
                                            sliptNum.addAndGet(resRule.getDataNum());
                                            if (null != deviceData) {
                                                //redis缓存
                                                if(null != device.getJcqdz()){
                                                    redisDataList.put(DeviceConstants.DEVICE_VALUE+device.getJcqdz(),deviceData.getEquivalentValue());
                                                }
                                                 //告警
                                                DevicePoint depotPoint = devicePointService.getById(pointRuleRef.getPointId());
                                                String thresholdOperators = sysDictDataService.selectDictLabel(DeviceConstants.THRESHOLD_OPERATOR, resRule.getThresholdOperator());
                                                DeviceAlarm alarm = DataUtil.packAlarm(resRule, deviceData.getEquivalentValue(), device, depotPoint,thresholdOperators);
                                                if (null != alarm) {
                                                    status.set(false);
                                                    alarmList.add(alarm);
                                                    deviceData.setAlarmType(1);
                                                }else{
                                                    status.set(true);
                                                    deviceData.setAlarmType(0);
                                                }
                                                addList.add(deviceData);
                                            }
                                        } catch (Exception e) {
                                            throw new RuntimeException(e);
                                        }
                                    }
                                });
                                statusMap.put(device.getId(), status.get());
                            }
                        }
                    }
                }
            }

        });
        //保存设备数据
        if (CollectionUtils.isNotEmpty(addList)) {
            deviceDataService.saveBatch(addList);
        }
        //保存设备告警数据
        if (CollectionUtils.isNotEmpty(alarmList)) {
            deviceAlarmService.saveBatch(alarmList);
        }
        //更新设备告警状态
        if (CollectionUtils.isNotEmpty(statusMap)) {
            for (Long deviceId : statusMap.keySet()) {
                deviceDeviceService.editDeviceStatus(deviceId, statusMap.get(deviceId));
            }
        }
        //更新redis缓存
        if (CollectionUtils.isNotEmpty(redisDataList)) {
            for (String key : redisDataList.keySet()) {
                redisTemplate.opsForValue().set(key, redisDataList.get(key));
            }
        }
        //更新首页实时数据值
        /*HomePageDataVO list = deviceDeviceService.getData();
        WebSocketUsers.sendMessageToUserByText(DeviceConstants.VUE_MSG_CLINET_9998, JSON.toJSONString(list));*/
    }

    /**
     * @param resRule
     * @param data
     * @param beginIndex
     * @param endIndex
     */
    private DeviceData packData(IotDataResRule resRule, List<String> data, int beginIndex, int endIndex, Long deviceId, Long pointId, String date) throws Exception {
        String data1 = data.subList(beginIndex, endIndex).stream().collect(Collectors.joining());
        return ruleData(resRule, data1, deviceId, pointId, date);
    }

    /**
     * 封装设备c1p1+c2p2+对象编码
     *
     * @param device
     * @return
     */
    private List<String> packDeviceAnalyzeStr(DeviceDevice device) {
        List<String> codes = new ArrayList<String>();
        String str = "";
        if("1".equals(device.getIsDt())){
            if (StringUtils.isNotEmpty(device.getAddressBitmap()) && StringUtils.isNotEmpty(device.getDxbh())) {
                str = device.getAddressBitmap() + "," + device.getDxbh() + ",";
                codes.add(str);
            }
        }else{
            //主测点不为空
            if(StringUtils.isNotEmpty(device.getMasterCode())){
                String addressBitmap = redisTemplate.opsForValue().get(DeviceConstants.GGD);
                String bitMap = null;
                //主测点与公共点组成一个测试点
                if(StringUtils.isNotEmpty(addressBitmap)){
                    bitMap = device.getMasterCode() + "," + addressBitmap + "," + device.getDxbh() + ",";
                    codes.add(bitMap);
                }
                //主测点与每个从测点组成一个测试点
                if(StringUtils.isNotEmpty(device.getSlaveCode())){
                    String[] slaveCodes = device.getSlaveCode().split(",");
                    for(int i = 0; i < slaveCodes.length; i++){
                        bitMap = device.getMasterCode() + "," +slaveCodes[i] + "," + device.getDxbh() + ",";
                        codes.add(bitMap);
                    }
                }
            }
        }

        return codes;
    }

    /**
     * 封装和缓存设备状态
     *
     * @param data
     */
    private void packDeviceSystemStatus(String data, Long deptId) {
        DeviceSystemStatus systemStatus = new DeviceSystemStatus();
        systemStatus.setQury(DeviceConstants.SYS_STATUS_WC_WWC.get(Character.toString(data.charAt(0))));
        systemStatus.setCldz(DeviceConstants.SYS_STATUS_WC_WWC.get(Character.toString(data.charAt(1))));
        systemStatus.setNbqsc(DeviceConstants.SYS_STATUS_GB_SC.get(Character.toString(data.charAt(2))));
        systemStatus.setFs(DeviceConstants.SYS_STATUS_GB_KQ.get(Character.toString(data.charAt(3))));
        systemStatus.setCxb(DeviceConstants.SYS_STATUS_ZC_BZX.get(Character.toString(data.charAt(4))));
        systemStatus.setHlb(DeviceConstants.SYS_STATUS_ZC_BZX.get(Character.toString(data.charAt(5))));
        systemStatus.setKzb(DeviceConstants.SYS_STATUS_ZC_BZX.get(Character.toString(data.charAt(6))));
        systemStatus.setNbdyb(DeviceConstants.SYS_STATUS_ZC_BZX.get(Character.toString(data.charAt(7))));
        systemStatus.setZhb(DeviceConstants.SYS_STATUS_ZC_BZX.get(Character.toString(data.charAt(8))));
        systemStatus.setZhb(DeviceConstants.SYS_STATUS_ZC_BZX.get(Character.toString(data.charAt(8))));
        systemStatus.setDqwzxzx(DeviceConstants.SYS_STATUS_ZC_BZX.get(Character.toString(data.charAt(9))));
        systemStatus.setDeptId(deptId);
        SysDept dept = deptService.selectDeptById(deptId);
        if (null != dept) {
            systemStatus.setDeptName(dept.getDeptName());
        }
        if(null != systemStatus && "1".equals(systemStatus.getQury())){
            boolean exists = redisTemplate.hasKey("yj_data_status");
            boolean flag = false;
            if(exists){
                String yjStatus = redisTemplate.opsForValue().get("yj_data_status");
                if(StringUtils.isEmpty(yjStatus) || "0".equals(yjStatus)){
                    flag = true;
                }
            }
            if(!exists || flag){
                DeviceCommand command  = deviceCommandService.getById(42L);
                List<DeviceCommand> commands = new ArrayList<>();
                commands.add(command);
                List<IotSerial> serials = iotSerialService.list();
                if(CollectionUtils.isNotEmpty(serials)){
                    serials = serials.stream().filter(iotSerial -> iotSerial.getDeptId() == deptId).collect(Collectors.toList());
                    JSONObject json = new JSONObject();
                    json.put("serial", serials.get(0));
                    json.put("commands", commands);
                    if (null != dept) {
                        json.put("deptName", dept.getDeptName());
                    }
                    WebSocketUsers.sendMessageToUserByText(deptId + "", json.toJSONString());
                    redisTemplate.opsForValue().set("yj_data_status","1");
                }
            }
        }
        redisTemplate.opsForValue().set(deptId + "sys_status", JSONObject.toJSONString(systemStatus));
    }


    /**
     * 解析数据
     *
     * @param resRule
     * @param data
     */
    private DeviceData ruleData(IotDataResRule resRule, String data, Long deviceId, Long pointId, String date) throws Exception {
        String dataTypes = sysDictDataService.selectDictLabel(DeviceConstants.DATA_TYPE, resRule.getDataType());
        String actualValue = "";
        //十进制数据判断，只要不是配置的10进制数据，均转换为10进制数据
        if (dataTypes.contains("二进制")) {
            BigInteger sint = new BigInteger(data, 16);
            //10进制转2进制
            data = sint.toString(2);
        } else if (dataTypes.contains("十六进制")) {
            data = String.valueOf(Integer.parseInt(data, 16));
        }
        actualValue = data;
        //计算data值
        //运算符
        String operatorUnit = sysDictDataService.selectDictLabel(DeviceConstants.OPERATOR_UNIT, resRule.getOperatorUnit());
        data = DataUtil.getDataValue(resRule, data,operatorUnit);
        //告警处理
        if ("Boolean".equals(dataTypes)) {
            //设备告警
            //Boolean类型为开关量
            //通信告警
        } else if (dataTypes.contains("二进制")) {
            //告警
            String dataBit = data;
        }
        return packDeviceData(data, resRule, deviceId, pointId, date, actualValue);
    }



    private DeviceData packDeviceData(String data, IotDataResRule resRule, Long deviceId, Long pointId, String date, String actualValue) throws Exception {
        DeviceData deviceData = new DeviceData();
        deviceData.setDeviceId(deviceId);
        deviceData.setPointId(pointId);
        deviceData.setActualValue(actualValue);
        deviceData.setEquivalentValue(data);
        deviceData.setDataUnit(sysDictDataService.selectDictLabel(DeviceConstants.DATA_UNIT, resRule.getDataUnit()));
        deviceData.setTs(DateUtil.StringToTimestamp(date));
        deviceData.setPoint(devicePointService.getById(pointId));
        DeviceDevice device = deviceDeviceService.getById(deviceId);
        deviceData.setDeviceName(device.getDeviceName());
        /*if(null != device){
            if(device.getDeviceName().contains("电阻")){
                deviceData.setDataType(0);
            }else{
                deviceData.setDataType(1);
            }
        }*/
        return deviceData;
    }







    @Override
    public IotSerial getSerialByTypeId(Long typeId) {
        Long serialId = deviceTypeSerialRefService.getSerialId(typeId);
        if (null == serialId) {
            return null;
        }
        IotSerial serial = this.getById(serialId);
        return serial;
    }

    @Override
    public void closePort(IotSerial serial) {
        //关闭串口
        JSONObject data = new JSONObject();
        data.put("closeCOM", "1");
        data.put("coms", serial.getSerialCode());
        WebSocketUsers.sendMessageToUserByText(serial.getDeptId() + "", data.toJSONString());
    }

    @Override
    public void editGather(IotSerial serial, String status) {
        JSONObject json = new JSONObject();
        json.put("openFlag", status);
        json.put("serial", serial);
        if ("0".equals(status)) {
            //串口下的校验
            List<IotDataCheck> dataChecks = iotDataCheckService.getIotDataCheckListBySerialId(serial.getId());
            if (com.baomidou.mybatisplus.core.toolkit.CollectionUtils.isEmpty(dataChecks)) {
                throw new RuntimeException("该类型绑定的串口,无校验信息，无法采集数据!");
            } else {
                json.put("dataChecks", dataChecks);
            }
        }
        WebSocketUsers.sendMessageToUserByText(serial.getDeptId() + "", json.toJSONString());
        this.updateById(serial);
    }

    @Override
    public void sendCommand(Long deptId, String command,String commandName) {
        LambdaQueryWrapper<IotSerial> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(IotSerial::getDeptId,deptId);
        wrapper.eq(IotSerial::getStatus,"0");
        wrapper.eq(IotSerial::getDelFlag,"0");
        List<IotSerial> list = this.list(wrapper);
        if(CollectionUtils.isNotEmpty(list)){
            DeviceCommand deviceCommand = new DeviceCommand();
            deviceCommand.setId(-1L);
            deviceCommand.setName(commandName);
            deviceCommand.setCommand(command);
            List<DeviceCommand> commands = new ArrayList<>();
            commands.add(deviceCommand);
            SysDept dept = deptService.selectDeptById(deptId);
            list.stream().forEach(serial->{
                JSONObject json = new JSONObject();
                json.put("serial", serial);
                json.put("commands", commands);
                if (null != dept) {
                    json.put("deptName", dept.getDeptName());
                }
                WebSocketUsers.sendMessageToUserByText(deptId + "", json.toJSONString());
            });
        }
    }

    @Override
    public void closeGather(Long deptId) {
        LambdaUpdateWrapper<IotSerial> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(IotSerial::getDeptId,deptId);
        wrapper.eq(IotSerial::getStatus,"0");
        wrapper.eq(IotSerial::getDelFlag,"0");
        wrapper.set(IotSerial::getGatherType,"1");
        this.update(wrapper);
    }
}
